<?php
/**
 * @version $Id: element.php 001 2008-07-24 17:27:23Z userxp $
 * @package JT.Library HTML Elements Classes
 *
 * HTML Basic Element Class
 * @copyright Copyright (C) 2005-2007 JoomlaTune Projects. All rights reserved.
 * @license http://creativecommons.org/ Creative Common License
 * @developed by Alexey Brin aka UserXP
 * 
 * web: http://joomlatune.ru
 * email: userxp@joomlaportal.ru
 *
 **/

defined('_VALID_MOS') or defined('_JEXEC') or die('Direct Access to this location is not allowed.');

class JXHtmlElement
{
	/** @var string Tag name of Element */
	var $start_tag	= '';
	
	/** @var string End of tag. If empty then Element is written as <tag /> style */
	var $finish_tag	= '';
	
	/** @var string Inner (html) text for filling from outside (for. ex. text for TD or DIV) */
	var $inner_text	= '';
	
	/** @var array Options (parameters) array */
	var $options	= null;
	
	/** @var object Children Elements */
	var $children	= null;
	
	/** @var string Builded Output of Element */
	var $output		= '';
	
	/** @var string Leading html-code indent */
	var $indent		= '';
	
	/** @var object Container for this element (usualy you can use DIV) */
	var $container	= null;
	
	/**
	 * Class constructor for PHP4
	 * 
	 * @param array Options
	 *
	 * @since 1.0
	 */
	function JXHtmlElement( $options=null ) {
		$this->__construct( $options );
	} //JXHtmlElement
	
	/**
	 * Class constructor for PHP5
	 * 
	 * @param array Options
	 *
	 * @since 1.0
	 */
	function __construct( $options=null ) {
		$this->setOptions( $options );
		$this->init( $options );
	} //__construct
	
	// abstract
	function init()	{} //init
	
	// abstract
	function create() {} //create
	
	// abstract (default) AJAX Response handler
	function axResponser() {
		return '-=:: AJAX RESPONSE HANDLER ::=-';
	} //axResponser
	
	/**
	 * Default AJAX-response function registrator
	 * 
	 * @return array Options
	 *
	 * @since 1.0
	 */
	function registerHandler( $id ) {
		$id				= (string) $id;
		$class_name		= get_class( $this );
		$method_name	= 'axResponser';
		
		if( class_exists( 'JXLibrary' ) ) {
			$jxlib = & JXLibrary::getInstance();
			// $id, $class_name, $method_name='axResponser'
			$jxlib->registerAjaxHandlers( $id, $class_name, $method_name );
			return true;
		}
		else return false;
	} //registerHandler
	
	/**
	 * Returns parameters of element
	 * 
	 * @return array Options
	 * @since 1.0
	 */
	function getOptions() {
		return $this->options;
	} //getOptions
	
	/**
	 * Sets parameters of element
	 * 
	 * @param mixed Array or object of options
	 * @param bool Specified append options or overwrite existent
	 *
	 * @return array Returns options
	 * @since 1.0
	 */
	function setOptions( $options, $append=false ) {
		$result = array();
		if( is_object( $options ) )
		{
			// Converts object to array
			foreach( $options as $key=>$value ) {
				$result[$key] = $value;
			}
			$options = & $result;
		}
		
		if( is_array( $options ) ) {
			if( $append ) {
				$this->options = $this->options + $options; //appends array
			}
			else {
				$this->options = $options;
			}
		}
		else {
			$this->options = null;
		}
		
		return $this->options;
	} //setOptions
	
	/**
	 * Clears parameters of element
	 * 
	 * @since 1.0
	 */
	function clear() {
		$this->options		= null;
		$this->output		= '';
		$this->inner_text	= '';
	} //clear
	
	/**
	 * Returns value of specified parameter
	 * 
	 * @return mixed Value of parameter
	 * 
	 * @since 1.0
	 */
	function getParameter( $string ) {
		if( !is_string( $string ) ) return false;
		
		if( is_array( $this->options ) )
		{
			if( isset( $this->options[$string] ) ) {
				return $this->options[$string];
			}
			else {
				return false;
			}
		}
		// this is for case if options is binded for external object not array
		elseif( is_object( $this->options ) )
		{
			if( isset( $this->options->$string ) ) {
				return $this->options->$string;
			}
			else {
				return false;
			}
		}
		return false;
	} //getOptions

	/**
	 * Sets value of specified parameter
	 * 
	 * @return bool Returns true if sucsessful
	 * 
	 * @since 1.0
	 */
	function setParameter( $string, $value='', $check_empty=true ) {
		if( !is_string( $string ) ) return false;
		if( $this->options === null ) $this->options = array();
		
		if( $check_empty && empty( $value ) ) return false;
		
		$value	= strval( $value );
		
		if( is_array( $this->options ) ) {
			$this->options[$string] = $value;
		}
		elseif( is_object( $this->options ) ) {
			$this->options->$string = $value;
		}
		
		return true;
	} //setParameter
	
	/**
	 * Unsets value of specified parameter
	 * 
	 * @return bool Returns true if sucsessful
	 *
	 * @since 1.0
	 */
	function unsetParameter( $string ) {
		if( !is_string( $string ) ) return false;
		
		// this is for case if options is binded for external object not array
		if( is_object( $this->options ) )
		{
			if( isset( $this->options->$string ) ) {
				unset( $this->options->$string );
				return true;
			}
		}
		elseif( is_array( $this->options ) )
		{
			if( isset( $this->options[$string] ) ) {
				unset( $this->options[$string] );
				return true;
			}
		}
		return false;
	} //setParameter
	
	/**
	 * Adds child element
	 * 
	 * @param mixed Object for adding as child element
	 * @param int How many times to repeat addition
	 * @param bool Add oject/class as new or not
	 * 
	 * @since 1.0
	 */
	function addChild( $object, $times=1, $new=false ) {
		$times = (int) $times;
		for( $i=1; $i<=$times; $i++) {
			if( $new ) {
				$this->children[] = new $object;
			}
			else {
				$this->children[] = $object;
			}
		}
	}
	
	/**
	 * Binds external source of options
	 * 
	 * @param mixed Array or object of options
	 * @return bool Result
	 *
	 * @since 1.0
	 */
	function bindOptions( & $options ) {
		if( is_array( $options ) || is_object( $options ) ) {
			$this->options = & $options;
			return true;
		}
		else
		{
			return false;
		}
	} //setOptions
	
	/**
	 * Main function for building HTML-code for whole structure
	 * 
	 * @param bool Check saved output for already builded html
	 * @param bool Save builded values in element's output var
	 * @param bool Check children elements
	 * @return string HTML code
	 *
	 * @since 1.0
	 */
	function build( $check_default=true, $save=true, $check_children=false ) {
		if( !$this->start_tag ) {
			if( $save ) $this->output = '';
			return '';
		}
		
		$result = '';
		if( $check_default && !empty( $this->output) ) {
			$result = $this->output;
		}
		else {
			if( $check_children ) {
				if( is_object( $this->children ) ) {
					if( method_exists( $this->children, 'build' ) ) {
						$result .= $this->children->build( $check_default, $save, $check_children );
					}
				}
				elseif( is_array( $this->children ) ) {
					foreach( $this->children as $child ) {
						if( is_object( $child ) ) {
							if( method_exists( $child, 'build' ) ) {
								$result .= $child->build( $check_default, $save, $check_children );
							}
						}
						elseif( is_string( $child ) ) {
							$result .= (string) $child;
						}
					}
				}
			}
			
			$output = $this->indent . '<' . $this->start_tag . $this->optionsToString();
			if( $this->finish_tag ) {
				$output .= '>' . $result . $this->inner_text . $this->indent . '</' . $this->finish_tag . '>';
			}
			else {
				$output .= ' />';
			}
			$result = $output;
		}
		if( $save ) $this->output = $result;
		return $result;
	}
	
	/**
	 * Converts all element's options to string representation
	 * 
	 * @return string Options as HTML string
	 *
	 * @since 1.0
	 */
	function optionsToString() {
		$result = '';
		if( count( $this->options ) )
		foreach( $this->options as $key=>$value ) {
			$result .= ' '.$key.'="'.$value.'"';
		}
		return $result;
	} //optionsToString
	
	/**
	 * Disassemblies URL query
	 * 
	 * @return array Array of url query parts
	 *
	 * @since 1.0
	 */
	function linkExplode( $href='' ) {
		if( !$href ) return false;
		
		$jxlib = & JXLibrary::getInstance();
		$live = $jxlib->config->getValue( 'live_site' );
		//$path = str_replace( $live, '', $href );
		
		$str = parse_url( $href );
		$query = isset($str['query']) ? parse_str($str['query']) : '';
		
		$result = array( '_is_admin_'=>false );
		if( stristr( $path, 'administrator' ) !== false ) {
			$result = array( '_is_admin_'=>true );
		}
		if( count( $query ) ) $result = array_merge( $result, $query );
		
		return $result; 
	} //linkExplode
	
	/**
	 * Assemblies array into URL query
	 * 
	 * @return string URL
	 *
	 * @since 1.0
	 */
	function linkImplode( $query ) {
		if( !$query ) return false;
		
		$jxlib = & JXLibrary::getInstance();
		$result = $jxlib->config->getValue( 'live_site' ) . '/';
		if( isset( $query['_is_admin_'] ) ) {
			$result .= $query['_is_admin_'] ? 'administrator/' : '';
			unset( $query['_is_admin_'] );
		}
		$result .= 'index2.php';
		$spl = '?';
		foreach( $query as $key=>$value ) {
			$result .= $spl.$key.'='.$value;
			$spl = '&';
		}
		
		return $result;
	} //linkImplode
	
	function rawCheck() {
		echo "<pre>HTML Element Output Check: \n";
		print_r( htmlentities( $this->output ) ); // , ENT_NOQUOTES, 'UTF-8'
		echo "</pre>\n";
	} //rawCheck
}

